#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
+#include <linux/bitops.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
#include <asm/io.h>
*/
if ( unlikely(rx->status <= 0) )
{
- /* Gate this error. We get a (valid) slew of them on suspend. */
- if ( np->user_state == UST_OPEN )
- printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
+ printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
wmb();
np->rx->req_prod++;
mcl->args[2] = 0;
mcl++;
(void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
+
+#if 0
+ if (unlikely(rx_mcl[0].args[5] != 0))
+ printk(KERN_ALERT"Hypercall0 failed %u\n",np->rx->resp_prod);
+
+ if (unlikely(rx_mcl[1].args[5] != 0))
+ printk(KERN_ALERT"Hypercall1 failed %u\n",np->rx->resp_prod);
+#endif
+
}
while ( (skb = __skb_dequeue(&rxq)) != NULL )
printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n",
np->tx->req_prod,np->rx->req_prod);
+
/* Step 3: All public and private state should now be sane. Get
* ready to start sending and receiving packets and give the driver
* domain a kick because we've probably just requeued some
struct net_private *np = NULL;
int i;
+
+
#if 1
/* XXX THIS IS TEMPORARY */
// stop bad things from happening until we're back up
np->backend_state = BEST_DISCONNECTED;
+
+ memset(np->tx,0,PAGE_SIZE);
+ memset(np->rx,0,PAGE_SIZE);
cmsg.type = CMSG_NETIF_FE;
cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
- "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order)
+ "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order),
+ "D" (DOMID_SELF)
: "memory" );
return ret;
xcio_info(ioctxt, "\b\b\b\b100%%\nMemory reloaded.\n");
+ /* Get the list of PFNs that are not in the psuedo-phys map */
+ {
+ unsigned int count, *pfntab;
+ int rc;
+ if ( xcio_read(ioctxt, &count, sizeof(count)) )
+ {
+ xcio_error(ioctxt, "Error when reading from state file");
+ goto out;
+ }
+
+ pfntab = malloc( sizeof(unsigned int) * count );
+ if ( !pfntab )
+ {
+ xcio_error(ioctxt, "Out of memory");
+ goto out;
+ }
+
+ if ( xcio_read(ioctxt, pfntab, sizeof(unsigned int)*count) )
+ {
+ xcio_error(ioctxt, "Error when reading pfntab from state file");
+ goto out;
+ }
+
+ for(i=0;i<count;i++)
+ {
+ unsigned long pfn = pfntab[i];
+ pfntab[i]=pfn_to_mfn_table[pfn];
+ pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap
+ }
+
+ if ( count>0 )
+ {
+ if ( (rc = do_dom_mem_op( xc_handle,
+ MEMOP_decrease_reservation,
+ pfntab, count, 0, dom )) <0 )
+ {
+ xcio_error(ioctxt, "Could not decrease reservation : %d",rc);
+ goto out;
+ }
+ else
+ {
+ printf("Decreased reservation by %d pages\n", count);
+ }
+ }
+
+ }
+
+
if ( xcio_read(ioctxt, &ctxt, sizeof(ctxt)) ||
xcio_read(ioctxt, shared_info, PAGE_SIZE) )
goto out;
}
- printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n",
- op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
- ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
-
}
/* calculate the power of 2 order of nr_pfns, e.g.
goto out;
}
-printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n",
- op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
- ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
+ /* Send through a list of all the PFNs that were not in map at the close */
+ {
+ unsigned int i,j;
+ unsigned int pfntab[1024];
+
+ for ( i = 0, j = 0; i < nr_pfns; i++ )
+ {
+ if ( live_pfn_to_mfn_table[i] >= 0x80000000UL )
+ j++;
+ }
+
+ if ( xcio_write(ioctxt, &j, sizeof(unsigned int)) )
+ {
+ xcio_error(ioctxt, "Error when writing to state file (6a)");
+ goto out;
+ }
+
+ for ( i = 0, j = 0; i < nr_pfns; )
+ {
+ if ( live_pfn_to_mfn_table[i] >= 0x80000000UL )
+ {
+ pfntab[j++] = i;
+ }
+ i++;
+ if ( j == 1024 || i == nr_pfns )
+ {
+ if ( xcio_write(ioctxt, &pfntab, sizeof(unsigned long)*j) )
+ {
+ xcio_error(ioctxt, "Error when writing to state file (6b)");
+ goto out;
+ }
+ j = 0;
+ }
+ }
+ }
/* Map the suspend-record MFN to pin it. The page must be owned by
domid for this to succeed. */
out1: return ret;
}
+
+static inline int do_dom_mem_op(int xc_handle,
+ unsigned int memop,
+ unsigned int *extent_list,
+ unsigned int nr_extents,
+ unsigned int extent_order,
+ domid_t domid)
+{
+ privcmd_hypercall_t hypercall;
+ long ret = -EINVAL;
+
+ hypercall.op = __HYPERVISOR_dom_mem_op;
+ hypercall.arg[0] = (unsigned long)memop;
+ hypercall.arg[1] = (unsigned long)extent_list;
+ hypercall.arg[2] = (unsigned long)nr_extents;
+ hypercall.arg[3] = (unsigned long)extent_order;
+ hypercall.arg[4] = (unsigned long)domid;
+
+ if ( mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0 )
+ {
+ PERROR("Could not lock memory for Xen hypercall");
+ goto out1;
+ }
+
+ if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+ {
+ fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
+ " rebuild the user-space tool set?\n",ret,errno);
+ goto out2;
+ }
+
+ out2: (void)munlock(extent_list, nr_extents*sizeof(unsigned long));
+ out1: return ret;
+}
+
+
/*
* PFN mapping.
*/
long do_dom_mem_op(unsigned int op,
unsigned long *extent_list,
unsigned long nr_extents,
- unsigned int extent_order)
+ unsigned int extent_order,
+ domid_t domid)
{
- if ( op == MEMOP_increase_reservation )
- return alloc_dom_mem(current, extent_list, nr_extents, extent_order);
+ struct domain *d;
+ long rc = -ENOSYS;
- if ( op == MEMOP_decrease_reservation )
- return free_dom_mem(current, extent_list, nr_extents, extent_order);
+ if (domid == DOMID_SELF)
+ d = current;
+ else
+ d = find_domain_by_id(domid);
- return -ENOSYS;
+ if (d==NULL)
+ return -ESRCH;
+
+ switch( op )
+ {
+ case MEMOP_increase_reservation:
+ rc = alloc_dom_mem(d, extent_list, nr_extents, extent_order);
+ break;
+ case MEMOP_decrease_reservation:
+ rc = free_dom_mem(d, extent_list, nr_extents, extent_order);
+ break;
+ }
+
+ if (domid!=DOMID_SELF)
+ put_domain(d);
+
+ return rc;
}